home *** CD-ROM | disk | FTP | other *** search
/ PC Media 7 / PC MEDIA CD07.iso / share / prog / cm / cmtring.cc < prev    next >
Encoding:
Text File  |  1994-09-06  |  5.6 KB  |  276 lines

  1. // CmTRing.cc
  2. // -----------------------------------------------------------------
  3. // Compendium - C++ Container Class Library
  4. // Copyright (C) 1992-1994, Glenn M. Poorman, All rights reserved
  5. // -----------------------------------------------------------------
  6. // Ring (circular linked list) template implementation.
  7. // -----------------------------------------------------------------
  8.  
  9.  
  10. // "CmRing" is the ring copy constructor.
  11. //
  12. template <class T> CmTRing<T>::CmTRing(const CmTRing<T>& R)
  13.                              : CmTContainer<T>(R)
  14. {
  15.   _top = _last = NULL;
  16.   copy(R);
  17. }
  18.  
  19.  
  20. // "~CmTRing" is the ring destructor.
  21. //
  22. template <class T> CmTRing<T>::~CmTRing()
  23. {
  24.   removeAll();
  25. }
  26.  
  27.  
  28. // "=" assignment operator copies the specified ring into this ring.
  29. //
  30. template <class T> CmTRing<T>& CmTRing<T>::operator=(const CmTRing<T>& R)
  31. {
  32.   if (&R != this)
  33.   {
  34.     removeAll();
  35.     copy     (R);
  36.   }
  37.   return *this;
  38. }
  39.  
  40.  
  41. // "add" adds the specified item to the top of the ring.
  42. //
  43. template <class T> Bool CmTRing<T>::add(const T& rObj)
  44. {
  45.   CmTRingNode<T> *newnode = new CmTRingNode<T>(rObj);
  46.   if (!newnode) return FALSE;
  47.  
  48.   if (!_top)
  49.   {
  50.     _top = _last = newnode;
  51.     newnode->_next = _top;
  52.   }
  53.   else
  54.   {
  55.     newnode->_next = _top;
  56.     _top           = newnode;
  57.     _last->_next   = newnode;
  58.   }
  59.   _size++;
  60.   return TRUE;
  61. }
  62.  
  63.  
  64. // "remove" removes the first occurrence of an item which is equal to the
  65. // specified item.
  66. //
  67. template <class T> Bool CmTRing<T>::remove(const T& rObj)
  68. {
  69.   if (!_top) return FALSE;
  70.  
  71.   if (_top->_data == rObj) return removeTop();
  72.  
  73.   CmTRingNode<T> *rover1 = _top;
  74.   CmTRingNode<T> *rover2 = _top;
  75.  
  76.   while (rover1 != NULL && rover1->_data != rObj)
  77.   {
  78.     rover2 = rover1;
  79.     rover1 = rover1->_next;
  80.   }
  81.  
  82.   if (rover1 == NULL) return FALSE;
  83.  
  84.   if (rover1 == _last) _last = rover2;
  85.   rover2->_next = rover2->_next->_next;
  86.  
  87.   delete rover1;
  88.   _size--;
  89.   return TRUE;
  90. }
  91.  
  92.  
  93. // "removeTop" removes the top item from the ring.
  94. //
  95. template <class T> Bool CmTRing<T>::removeTop()
  96. {
  97.   if (!_top) return FALSE;
  98.  
  99.   if (_size == 1)
  100.   {
  101.     delete _top;
  102.     _top = _last = NULL;
  103.   }
  104.   else
  105.   {
  106.     CmTRingNode<T> *temp = _top;
  107.     _top = _top->_next;
  108.     _last->_next = _top;
  109.     delete temp;
  110.   }
  111.   _size--;
  112.   return TRUE;
  113. }
  114.  
  115.  
  116. // "lookup" returns the first occurrence of an item which is equal to
  117. // the specified item.
  118. //
  119. template <class T> const T& CmTRing<T>::lookup(const T& rObj) const
  120. {
  121.   if (!_top) return _error;
  122.   CmTRingNode<T> *rover = _top;
  123.   CmTRingNode<T> *temp  = NULL;
  124.   int             ii    = 0;
  125.   while (ii < _size && !temp)
  126.   {
  127.     if (rover->_data == rObj)
  128.       temp  = rover;
  129.     else
  130.     {
  131.       rover = rover->_next;
  132.       ii++;
  133.     }
  134.   }
  135.   return (temp) ? temp->_data : _error;
  136. }
  137.  
  138.  
  139. // "contains" returns TRUE if the ring contains an item which is equal
  140. // to the specified object.
  141. //
  142. template <class T> Bool CmTRing<T>::contains(const T& rObj) const
  143. {
  144.   if (!_top) return NULL;
  145.   CmTRingNode<T> *rover = _top;
  146.   int             ii    = 0;
  147.   Bool            found = FALSE;
  148.   while (ii < _size && !found)
  149.   {
  150.     if (rover->_data == rObj)
  151.       found = TRUE;
  152.     else
  153.     {
  154.       rover = rover->_next;
  155.       ii++;
  156.     }
  157.   }
  158.   return found;
  159. }
  160.  
  161.  
  162. // "occurrences" counts the number of items that are equal to the specified
  163. // item.
  164. //
  165. template <class T> unsigned CmTRing<T>::occurrences(const T& rObj) const
  166. {
  167.   if (!_top) return 0;
  168.   CmTRingNode<T> *rover = _top;
  169.   int             ii    = 0;
  170.   unsigned        occur = 0;
  171.   while (ii < _size)
  172.   {
  173.     if (rover->_data == rObj) occur++;
  174.     rover = rover->_next; ii++;
  175.   }
  176.   return occur;
  177. }
  178.  
  179.  
  180. // "removeAll" removes all of the items from the ring.
  181. //
  182. template <class T> void CmTRing<T>::removeAll()
  183. {
  184.   CmTRingNode<T> *rover = _top;
  185.   int             ii    = 0;
  186.   while (ii < _size)
  187.   {
  188.     CmTRingNode<T> *temp = rover->_next;
  189.     delete rover;
  190.     rover = temp;
  191.     ii++;
  192.   }
  193.   _top  = _last = NULL;
  194.   _size = 0;
  195. }
  196.  
  197.  
  198. // "top" returns a pointer to the top object in the ring.
  199. //
  200. template <class T> const T& CmTRing<T>::top() const
  201. {
  202.   return (_top) ? _top->_data : _error;
  203. }
  204.  
  205.  
  206. // "newIterator" creates and returns a new ring iterator.
  207. //
  208. template <class T> CmTIterator<T>* CmTRing<T>::newIterator() const
  209. {
  210.   return new CmTRingIterator<T>(*this);
  211. }
  212.  
  213.  
  214. // "done" checks to see if done iterating.  (Always FALSE for a ring.)
  215. //
  216. template <class T> Bool CmTRingIterator<T>::done() const
  217. {
  218.   return FALSE;
  219. }
  220.  
  221.  
  222. // "next" returns the current ring item and advances the iterator
  223. // to the next item.
  224. //
  225. template <class T> const T& CmTRingIterator<T>::next()
  226. {
  227.   if (!_node) return _ring._error;
  228.   CmTRingNode<T> *rval = _node;
  229.   _node = _node->_next;
  230.   return rval->_data;
  231. }
  232.  
  233.  
  234. // "previous" backs the iterator up one item and returns that item.
  235. //
  236. template <class T> const T& CmTRingIterator<T>::previous()
  237. {
  238.   if (!_node) return _ring._error;
  239.   const T& rval = _node->_data;
  240.  
  241.   if (_node == _ring._top)
  242.     _node = _ring._last;
  243.   else
  244.   {
  245.     CmTRingNode<T> *rover = _ring._top;
  246.     while (rover && rover->_next != _node)
  247.       rover = rover->_next;
  248.     _node = rover;
  249.   }
  250.   return rval;
  251. }
  252.  
  253.  
  254. // "current" returns the current object in the ring.
  255. //
  256. template <class T> const T& CmTRingIterator<T>::current() const
  257. {
  258.   return (_node) ? _node->_data : _ring._error;
  259. }
  260.  
  261.  
  262. // "first" moves the iterator to the first item.
  263. //
  264. template <class T> void CmTRingIterator<T>::first()
  265. {
  266.   _node = _ring._top;
  267. }
  268.  
  269.  
  270. // "last" moves the iterator to the last item.
  271. //
  272. template <class T> void CmTRingIterator<T>::last()
  273. {
  274.   _node = _ring._last;
  275. }
  276.